#pragma once

#include "../Xml/Forward.h"
#include "../Shared/GObjHelpers.hpp"

namespace BuildNG
{
  class Project;
  class BuildContext;
  class ErrorListener;
  
  class Module : public NamedObject
  {
  public:
    Module();

    virtual void load_from_xml(const Xml::Element &xml) = 0;
    virtual void save_to_xml(Xml::Element &xml) const = 0;

    virtual void build_dependency_graph() { }
    virtual bool build(BuildContext &context,Glib::RefPtr<ErrorListener> error_listener) = 0;

    bool build(const Glib::ustring &output_root_dir,
      Glib::RefPtr<ErrorListener> error_listener);

    const Glib::ustring& get_module_dir() const { return module_dir; }
    void set_module_dir(const Glib::ustring &module_dir) 
    {
      this->module_dir = module_dir;
    }

  private:
    Glib::ustring           module_dir;

    Glib::RefPtr<Project>   project;
  };
  
  struct ModuleTypeInfo
  {
    Glib::RefPtr<Module> (*create_func)();

    template <class T>
    static Glib::RefPtr<Module> ctor_wrapper()
    {
      return Glib::RefPtr<Module>(new T);
    }
  };
  
  void register_module_type(const Glib::ustring &name,const ModuleTypeInfo &module_type_info);
  const ModuleTypeInfo* get_module_type_info(const Glib::ustring &type_name);
}
